module ID_reg(
  input clk,
  input rst,
  input enable,
  input flush,
  input ready,

  //from Decode uint
  input valid_i,

  input [31:0] inst_i,

  input [63:0] pc_i,
  input [63:0] src1_i,
  input [63:0] src2_i,
  input [4:0] rs1_i,
  input [4:0] rs2_i,
  input [63:0] imm_i,
  input [4:0] dest_i,

  input [6:0] arithmetic_op_i,
  input [21:0] logic_op_i,
  input [7:0] branch_op_i,
  input [7:0] load_op_i,
  input [3:0] store_op_i,
  input [4:0] mul_op_i,
  input [7:0] div_op_i,
  input [7:0] csr_op_i,
  input [0:0] fence_op_i,
  input [1:0] other_op_i,
  input [0:0] unsupport_op_i,

  output [31:0] inst_o,

  output [63:0] pc_o,
  output [63:0] src1_o,
  output [63:0] src2_o,
  output [4:0] rs1_o,
  output [4:0] rs2_o,
  output [63:0] imm_o,
  output [4:0] dest_o,

  output [6:0] arithmetic_op_o,
  output [21:0] logic_op_o,
  output [7:0] branch_op_o,
  output [7:0] load_op_o,
  output [3:0] store_op_o,
  output [4:0] mul_op_o,
  output [7:0] div_op_o,
  output [7:0] csr_op_o,
  output [0:0] fence_op_o,
  output [1:0] other_op_o,
  output [0:0] unsupport_op_o,

  output valid_o
);
  localparam NUM_WIDTH = 64+64+64+5+5+64+5;
  wire [NUM_WIDTH-1:0] inst_num_i = {pc_i,src1_i,src2_i,rs1_i,rs2_i,imm_i,dest_i};
  wire [NUM_WIDTH-1:0] inst_num_o;
  Reg #(.WIDTH(NUM_WIDTH), .RESET_VAL({NUM_WIDTH{1'b0}})) reg_num (.clk(clk), .rst(rst|flush), .din(inst_num_i), .dout(inst_num_o), .wen(enable));
  assign {pc_o,src1_o,src2_o,rs1_o,rs2_o,imm_o,dest_o} = inst_num_o;
  
  localparam OP_WIDTH = 7+22+8+8+4+5+8+8+1+2+1;
  wire [OP_WIDTH-1:0] inst_op_i = {arithmetic_op_i,logic_op_i,branch_op_i,load_op_i,store_op_i,mul_op_i,div_op_i,csr_op_i,fence_op_i,other_op_i,unsupport_op_i};
  wire [OP_WIDTH-1:0] inst_op_o;
  Reg #(.WIDTH(OP_WIDTH), .RESET_VAL({OP_WIDTH{1'b0}})) reg_op (.clk(clk), .rst(rst|flush), .din(inst_op_i), .dout(inst_op_o), .wen(enable));
  assign {arithmetic_op_o,logic_op_o,branch_op_o,load_op_o,store_op_o,mul_op_o,div_op_o,csr_op_o,fence_op_o,other_op_o,unsupport_op_o} = inst_op_o&{OP_WIDTH{ready}};
  
  wire op_valid_o;
  Reg #(.WIDTH( 1), .RESET_VAL(1'b0)) reg_valid (.clk(clk), .rst(rst|flush), .din(valid_i),   .dout(op_valid_o), .wen(enable));
  assign valid_o = op_valid_o&ready;

  Reg #(.WIDTH(32), .RESET_VAL(32'b0)) reg_inst (.clk(clk), .rst(rst|flush), .din(inst_i),   .dout(inst_o), .wen(enable));


endmodule
